home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / sys5 / iscwmpst.z / iscwmpst / tcp / isc-src / convers / conv2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-29  |  6.4 KB  |  246 lines

  1. static char  rcsid[] = "@(#) $Header: chat.c,v 2.1 90/03/04 20:18:18 dl9sau Exp $";
  2.  
  3. #include <sys/types.h>
  4.  
  5. #include <ctype.h>
  6. #include <signal.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <sys/socket.h>
  10. #include <termio.h>
  11. #include <sys/time.h>
  12.  
  13. #define SERVER "*:3600"
  14. #define RCFILE  ".convrc"
  15. #define EINCONF "convers: error in config -- %s"
  16. #define USAGE   "usage: convers [-c channel][-s host:service][-n name][-i invite][-l l][-w l]\n"
  17.  
  18. extern char  *getenv();
  19. extern char  *optarg;
  20. extern int  optind;
  21. extern struct sockaddr *build_sockaddr();
  22. extern void exit();
  23. extern void perror();
  24.  
  25. static struct termio prev_termio;
  26.  
  27. /*---------------------------------------------------------------------------*/
  28.  
  29. static void sigpipe_handler(sig, code, scp)
  30. int  sig, code;
  31. /* struct sigcontext *scp; */
  32. {
  33.   /* scp->sc_syscall_action = SIG_RETURN; */
  34. }
  35.  
  36. /*---------------------------------------------------------------------------*/
  37.  
  38. static void stop(arg)
  39. char  *arg;
  40. {
  41.   if (arg) perror(arg);
  42.   ioctl(0, TCSETA, &prev_termio);
  43.   exit(0);
  44. }
  45.  
  46. /*---------------------------------------------------------------------------*/
  47.  
  48. static int  scan_config(server, name, channel, commands)
  49. char  *server, *name;
  50. int  *channel;
  51. char  *commands;
  52. {
  53.   FILE * fp = (FILE *) 0;
  54.   char  buf1[1024], buf2[128];
  55.   char  *p, *q;
  56.   int  i;
  57.  
  58.   sprintf(buf2, "%s/%s", getenv("HOME"), RCFILE);
  59.   *commands = '\0';
  60.   if (!(fp = fopen(buf2, "r")))
  61.     return 1;
  62.   while (fgets(buf1, sizeof(buf1), fp)) {
  63.     if (*buf1 == '\n' || *buf1 == '#') continue;
  64.     for ((p = buf1, i = 0); *p; p++)
  65.       if (*p == ':') i++;
  66.     if (i >= 2) {
  67.       for ((q = buf2, p = buf1); *p != ':'; *q++ = *p++) ;
  68.       *q='\0';
  69.       p++;
  70.  
  71.       q = strrchr(p, ':');
  72.       *q = '\0';
  73.       if (!strcmp(buf2, "server"))  strcpy(server, p);
  74.       else if (!strcmp(buf2, "name"))  strcpy(name, p);
  75.       else if (!strcmp(buf2, "channel"))  *channel = atoi(p);
  76.       else {
  77.         fprintf(stderr, EINCONF, buf1);
  78.         stop(0);
  79.       }
  80.     }
  81.     else {
  82.         if (strchr(buf1, "/c")) {
  83.           fprintf(stderr, EINCONF, buf1);
  84.           stop(0);
  85.         } 
  86.         strcat(commands, buf1);
  87.      }
  88.   }
  89.   fclose(fp);
  90.   return 0;
  91. }
  92.  
  93. /*---------------------------------------------------------------------------*/
  94.  
  95. main(argc, argv)
  96. int  argc;
  97. char  **argv;
  98. {
  99.  
  100.   char  *server = SERVER;
  101.   char  name[16];
  102.   char  commands[1028];
  103.   char  buffer[2048];
  104.   char  c;
  105.   char  *p, *q;
  106.   char  inbuf[2048];
  107.   char  outbuf[2048];
  108.   int  addrlen;
  109.   int  ch;
  110.   int  channel = 0;
  111.   int  errflag = 0;
  112.   int  echo;
  113.   int  i;
  114.   int  incnt = 0;
  115.   int  mask;
  116.   int  outcnt = 0;
  117.   int  size;
  118.   /* struct sigvec vec; */
  119.   struct sockaddr *addr;
  120.   struct termio curr_termio;
  121.  
  122.   /* vec.sv_mask = vec.sv_flags = 0; */
  123.   /* vec.sv_handler = sigpipe_handler; */
  124.   /* sigvector(SIGPIPE, &vec, (struct sigvec *) 0); */
  125.  
  126.   if (ioctl(0, TCGETA, &prev_termio)) stop(*argv);
  127.   if (ioctl(0, TCGETA, &curr_termio)) stop(*argv);
  128.   echo = curr_termio.c_lflag & ECHO;
  129.   curr_termio.c_lflag = 0;
  130.   curr_termio.c_cc[VMIN] = 1;
  131.   curr_termio.c_cc[VTIME] = 0;
  132.   if (ioctl(0, TCSETA, &curr_termio)) stop(*argv);
  133.  
  134.   strcpy(name, getenv("LOGNAME"));
  135.   /* scan_config(socket, name, &channel, commands); */
  136.   scan_config(server, name, &channel, commands);
  137.  
  138.   while ((ch = getopt(argc, argv, "c:i:l:n:s:w:")) != EOF)
  139.     switch (ch) {
  140.     case 'c':
  141.       channel = atoi(optarg);
  142.       break;
  143.     case 's':
  144.       server = optarg;
  145.       break;
  146.     case 'n':
  147.       strcpy(name, optarg);
  148.       break;
  149.     case 'l':
  150.       if (p = q = strchr(commands, "/l")) {     /* Alten Befehl entfernen */
  151.         for (q; (*q && *q != '\n'); q++) ;
  152.         if (*q++) {
  153.           while (*p++ = *q++) ;
  154.         }
  155.       }
  156.      break;
  157.       strcat(commands, "/l ");
  158.       if (*optarg == 'q' || *optarg == 'l')
  159.         strcat(commands, optarg);
  160.       strcat(commands, "\n");
  161.       break;
  162.     case 'w':
  163.       if (p = q = strchr(commands, "/w")) {     /* Alten Befehl entfernen */
  164.         for (q; (*q && *q != '\n'); q++) ;
  165.         if (*q++) {
  166.           while (*p++ = *q++) ;
  167.         }
  168.       }
  169.       strcat(commands, "/w ");
  170.       if (*optarg == 'q' || *optarg == 'l')
  171.         strcat(commands, optarg);
  172.       strcat(commands, "\n");
  173.       break;
  174.     case 'i':
  175.       sprintf(commands, "/i %s\n",  optarg);
  176.       break;
  177.     case '?':
  178.       errflag = 1;
  179.       break;
  180.     }
  181.  
  182.   if (errflag || optind < argc || !(addr = build_sockaddr(server, &addrlen))) {
  183.     fprintf(stderr, USAGE);
  184.     stop(0);
  185.   }
  186.   close(3);
  187.   if (socket(addr->sa_family, SOCK_STREAM, 0) != 3) stop(*argv);
  188.   if (connect(3, addr, addrlen)) stop(*argv);
  189.  
  190.   sprintf(inbuf, "/NAME %s %d\n", name, channel);
  191.   strcat(inbuf, commands);
  192.  
  193.   if (write(3, inbuf, (unsigned) strlen(inbuf)) < 0) stop(*argv);
  194.   for (; ; ) {
  195.     mask = 011;
  196.     select(4, &mask, 0, 0, (struct timeval *) 0);
  197.     if (mask & 1) {
  198.       do {
  199.         if ((size = read(0, buffer, sizeof(buffer))) <= 0) stop(0);
  200.         for (i = 0; i < size; i++) {
  201.           c = buffer[i];
  202.           if (c == '\r') c = '\n';
  203.           if (c == prev_termio.c_cc[VERASE]) {
  204.             if (incnt) {
  205.               incnt--;
  206.               if (echo && write(1, "\b \b", 3) < 0) stop(*argv);
  207.             }
  208.           } else if (c == prev_termio.c_cc[VKILL]) {
  209.             for (; incnt; incnt--)
  210.               if (echo && write(1, "\b \b", 3) < 0) stop(*argv);
  211.           } else if (echo && c == 18) {
  212.             if (write(1, "^R\n", 3) < 0) stop(*argv);
  213.             if (write(1, inbuf, (unsigned) incnt) < 0) stop(*argv);
  214.           } else {
  215.             inbuf[incnt++] = c;
  216.             if (echo && write(1, &c, 1) < 0) stop(*argv);
  217.           }
  218.           if (c == '\n' || incnt == sizeof(inbuf) - 1) {
  219.             if (*inbuf == '!') {
  220.               inbuf[incnt] = '\0';
  221.               if (ioctl(0, TCSETA, &prev_termio)) stop(*argv);
  222.               system(inbuf + 1);
  223.               if (ioctl(0, TCSETA, &curr_termio)) stop(*argv);
  224.               if (write(1, "!\n", 2) < 0) stop(*argv);
  225.             } else {
  226.               if (write(3, inbuf, (unsigned) incnt) < 0) stop(*argv);
  227.             }
  228.             incnt = 0;
  229.           }
  230.         }
  231.       } while (incnt);
  232.     } else {
  233.       size = read(3, buffer, sizeof(buffer));
  234.       if (size <= 0) stop(0);
  235.       for (i = 0; i < size; i++) {
  236.         c = buffer[i];
  237.         if (c != '\r') outbuf[outcnt++] = c;
  238.         if (c == '\n' || outcnt == sizeof(outbuf)) {
  239.           if (write(1, outbuf, (unsigned) outcnt) < 0) stop(*argv);
  240.           outcnt = 0;
  241.         }
  242.       }
  243.     }
  244.   }
  245. }
  246.